﻿using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using ReactiveGraph.Core;

namespace ReactiveGraph.Tests
{
    [TestFixture]
    public class RxCollectionTests
    {
        [Test]
        public void AddingOneElementWillNotify()
        {
            var collection = new RxCollection<string>();
            var list = new List<ChangedArgs<string>>();
            collection.Changed.Do(list.Add).Subscribe();
            collection.Add("a");
            list.Single().AddedItems.Should().BeEquivalentTo(new[]{"a"});
            list.Single().StartingIndex.Should().Be(0);
            collection.Add("b");
            list.Last().AddedItems.Should().BeEquivalentTo(new[] { "b" });
            list.Last().StartingIndex.Should().Be(1);
            
        }

        [Test]
        public void AddingRangeElementWillNotifyBatch()
        {
            var collection = new RxCollection<string>();
            var list = new List<ChangedArgs<string>>();
            collection.Changed.Do(list.Add).Subscribe();
            collection.AddRange("a","b","c");
            list.Single().AddedItems.Should().BeEquivalentTo(new[]{"a","b","c"});
            list.Single().StartingIndex.Should().Be(0);
            collection.AddRange("d", "e");
            list.Last().AddedItems.Should().BeEquivalentTo(new[] {"d","e"});
            list.Last().StartingIndex.Should().Be(3);
        }

        [Test]
        public void RemoveItemWillNotify()
        {
            var collection = new RxCollection<string>();
            collection.AddRange("a", "b", "c");
            var list = new List<ChangedArgs<string>>();
            collection.Changed.Do(list.Add).Subscribe();
            collection.Remove("b");
            list.Single().RemovedItems.Should().BeEquivalentTo(new[] { "b" });
            list.Single().StartingIndex.Should().Be(1);
        }

        [Test]
        public void ReplaceWillNotify()
        {
            var collection = new RxCollection<string>();
            collection.AddRange("a", "b", "c");
            var list = new List<ChangedArgs<string>>();
            collection.Changed.Do(list.Add).Subscribe();
            collection[1] = "x";
            list.Single().RemovedItems.Should().BeEquivalentTo(new[] { "b" });
            list.Single().AddedItems.Should().BeEquivalentTo(new[] { "x" });
            list.Single().StartingIndex.Should().Be(1);
        }

        [Test]
        public void ClearWillNotify()
        {
            var collection = new RxCollection<string>();
            collection.AddRange("a", "b", "c");
            var list = new List<ChangedArgs<string>>();
            collection.Changed.Do(list.Add).Subscribe();
            collection.Clear();
            list.Single().RemovedItems.Should().BeEquivalentTo(new[] { "a", "b", "c" });
            list.Single().AddedItems.Should().BeEmpty();
            list.Single().StartingIndex.Should().Be(0);
        }
    }
}
